package com.itservice.supporter_navi;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.util.Log;

import com.google.android.gcm.GCMBaseIntentService;
import com.itservice.supporter_navi.MarathonDataBase.MarathonDataBase;
import com.itservice.supporter_navi.MarathonDataBase.libs.DBUtilities;
import com.itservice.supporter_navi.utilities.CommonUtilities;
import com.itservice.supporter_navi.utilities.GCMSendMsg;


//=================================================================
// IntentService GCMから帰ってきたメッセージをハンドリングする処理
//=================================================================
public class GCMIntentService extends GCMBaseIntentService{
	private MarathonDataBase marathonDB; // データベースクラス


	// publicのコンストラクタ。親コンストラクタにセンダーIDを渡す。
	public GCMIntentService(){
		super(CommonUtilities.SENDER_ID);
		// データベースクラス取得
		//marathonDB = new MarathonDataBase(this);
		// DBインスタンス取得
        marathonDB = MarathonDataBase.getInstance();
	}


	// 登録インテントを受信した後に呼び出される。GCMから割り当てられる登録IDを取得することができる。
	@Override
	protected void onRegistered(Context context, String registrationId) {
		Log.i(CommonUtilities.LOG_TAG, "Device registered: regId = " + registrationId);
		marathonDB.setContext(context);
		marathonDB.setText(DBUtilities.USER_ID,registrationId);
	}

	// GCMから登録解除された後に呼び出される。
	@Override
	protected void onUnregistered(Context context, String registrationId) {
		Log.i(CommonUtilities.LOG_TAG, "Device unregistered: regId = " + registrationId);
	}


	// サードパーティサーバなどからGCMにメッセージ登録を行うとGCMはメッセージをデバイスに配信する。その時に呼び出される。
	@Override
	protected void onMessage(Context context, Intent intent) {
		// 受信したメッセージ毎にスレッドで処理
		marathonDB.setContext(context);
		Log.i(CommonUtilities.LOG_TAG, "受信しました！");
		MessageThread MessageThread = new MessageThread(context, intent);
		MessageThread.start();
	}



	//==================================================================================
	// 画面上部通知処理
	//==================================================================================
	// フレンド登録申請受信時のノーティフィケイション
    @SuppressLint("NewApi")
	private static void generateNotificationReg(Context context, String message) {
    	Intent notificationIntent = new Intent(context, MainActivity.class);
    	notificationIntent.putExtra(CommonUtilities.START_FLG, true);
    	notificationIntent.putExtra(CommonUtilities.NOTIFICATION_FRIEND_ID ,message);
    	PendingIntent pendingIntent =
    			PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    	//Notification.Builder builder = new Notification.Builder(context);
    	Builder builder = new NotificationCompat.Builder(context);

    	builder.setTicker("フレンド登録申請");
    	builder.setContentTitle("マラソン応援アプリ：フレンド登録申請");
       	builder.setContentText(message);
       	builder.setContentInfo("info");
       	builder.setWhen(System.currentTimeMillis());
       	builder.setContentIntent(pendingIntent);
       	builder.setSmallIcon(android.R.drawable.ic_menu_info_details);
       	Notification notification = builder.build();

        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(1, notification);
    }

    // フレンド登録完了時のノーティフィケーション
    @SuppressLint("NewApi")
	private static void generateNotificationOK(Context context, String message) {
    	Intent notificationIntent = new Intent(context, MainActivity.class);
    	PendingIntent pendingIntent =
    			PendingIntent.getActivity(context, 0, notificationIntent, 0);

    	//Notification.Builder builder = new Notification.Builder(context);
    	Builder builder = new NotificationCompat.Builder(context);

    	builder.setTicker("フレンド登録完了");
    	builder.setContentTitle("マラソン応援アプリ：フレンド登録完了");
       	builder.setContentText(message);
       	builder.setContentInfo("info");
       	builder.setWhen(System.currentTimeMillis());
       	builder.setContentIntent(pendingIntent);
       	builder.setSmallIcon(android.R.drawable.ic_menu_info_details);
       	Notification notification = builder.build();

        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(1, notification);
    }

    // フレンド申請、申請不許可時
    @SuppressLint("NewApi")
	private static void generateNotificationCancel(Context context, String message) {
    	Intent notificationIntent = new Intent(context, MainActivity.class);
    	PendingIntent pendingIntent =
    			PendingIntent.getActivity(context, 0, notificationIntent, 0);

    	//Notification.Builder builder = new Notification.Builder(context);
    	Builder builder = new NotificationCompat.Builder(context);

    	builder.setTicker("フレンド登録申請不許可");
    	builder.setContentTitle("マラソン応援アプリ：フレンド申請不許可");
       	builder.setContentText(message);
       	builder.setContentInfo("info");
       	builder.setWhen(System.currentTimeMillis());
       	builder.setContentIntent(pendingIntent);
       	builder.setSmallIcon(android.R.drawable.ic_menu_info_details);
       	Notification notification = builder.build();

        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(1, notification);
    }

    // フレンド申請、認証キーエラーの場合
    @SuppressLint("NewApi")
	private static void generateNotificationNG(Context context, String message) {
    	Intent notificationIntent = new Intent(context, MainActivity.class);
    	PendingIntent pendingIntent =
    			PendingIntent.getActivity(context, 0, notificationIntent, 0);

    	//Notification.Builder builder = new Notification.Builder(context);
    	Builder builder = new NotificationCompat.Builder(context);

    	builder.setTicker("フレンド登録認証キーエラー");
    	builder.setContentTitle("マラソン応援アプリ：フレンド登録認証キーエラー");
       	builder.setContentText(message);
       	builder.setContentInfo("info");
       	builder.setWhen(System.currentTimeMillis());
       	builder.setContentIntent(pendingIntent);
       	builder.setSmallIcon(android.R.drawable.ic_menu_info_details);
       	Notification notification = builder.build();

        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        notification.flags = Notification.FLAG_AUTO_CANCEL;
        notificationManager.notify(1, notification);
    }

	// ゴールした時のNotification
 	@SuppressLint("NewApi")
 	private static void generateNotificationGoal(Context context, String message) {
     	Intent notificationIntent = new Intent(context, MainActivity.class);
     	PendingIntent pendingIntent =
     			PendingIntent.getActivity(context, 0, notificationIntent, 0);

     	//Notification.Builder builder = new Notification.Builder(context);
     	Builder builder = new NotificationCompat.Builder(context);

     	builder.setTicker("ゴールしました！");
     	builder.setContentTitle("マラソン応援アプリ：ゴール報告");
        	builder.setContentText(message);
        	builder.setContentInfo("info");
        	builder.setWhen(System.currentTimeMillis());
        	builder.setContentIntent(pendingIntent);
        	builder.setSmallIcon(android.R.drawable.ic_menu_info_details);
        	Notification notification = builder.build();

         NotificationManager notificationManager = (NotificationManager)
                 context.getSystemService(Context.NOTIFICATION_SERVICE);
         notification.flags = Notification.FLAG_ONGOING_EVENT;
         notificationManager.notify(CommonUtilities.NOTIFICATION_ID_GOLE, notification);
     }

 	// 相手に削除された時のNotification
  	@SuppressLint("NewApi")
  	private static void generateNotificationRelease(Context context, String message) {
      	Intent notificationIntent = new Intent(context, MainActivity.class);
      	PendingIntent pendingIntent =
      			PendingIntent.getActivity(context, 0, notificationIntent, 0);

      	//Notification.Builder builder = new Notification.Builder(context);
      	Builder builder = new NotificationCompat.Builder(context);

      	builder.setTicker("登録相手が登録を解除しました。");
      	builder.setContentTitle("マラソン応援アプリ：登録解除");
         	builder.setContentText(message);
         	builder.setContentInfo("info");
         	builder.setWhen(System.currentTimeMillis());
         	builder.setContentIntent(pendingIntent);
         	builder.setSmallIcon(android.R.drawable.ic_menu_info_details);
         	Notification notification = builder.build();

          NotificationManager notificationManager = (NotificationManager)
                  context.getSystemService(Context.NOTIFICATION_SERVICE);
          notification.flags = Notification.FLAG_ONGOING_EVENT;
          notificationManager.notify(CommonUtilities.NOTIFICATION_ID_GOLE, notification);
      }

    //=========================================================================
    // メッセージ送信処理
    //=========================================================================
    public class SendAsyncTask extends AsyncTask<String, String, Long> {
		private String[] mRegIds;
		private String mMsg;

	    public SendAsyncTask(String[] regId , String msg) {
	        this.mRegIds = regId;
	        this.mMsg = msg;
	    }

	    /**
	     * バックグランドで行う処理
	     */
	    @Override
	    protected Long doInBackground(String... params) {
	    	//ServerUtilities.sendMessage(mRegId,mMsg);
	        GCMSendMsg.SendMsg(mRegIds,mMsg);
	        return null;
	    }
	}

    //=========================================================================
    // メッセージ処理スレッド
    //=========================================================================
    public class MessageThread extends Thread{
    	Context m_Context;
    	Intent m_Intent;

    	// コンストラクタ
    	public MessageThread(Context context,Intent intent){
    		m_Context=context;
    		m_Intent = intent;
    	}

    	// スレッドメイン処理
    	public void run(){
    		String[] aray_msg;
    		String str = m_Intent.getStringExtra("message");
    		Log.i(CommonUtilities.LOG_TAG, "Received message:" + str);
    		aray_msg = str.split(",");

    		Log.i(CommonUtilities.LOG_TAG, aray_msg[0]);

            // 登録申請メッセージ
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_FRIEND_APP)){
        		// 登録人数取得
        		int RegNo = marathonDB.getInteger(DBUtilities.FRIEND_NUM, 0);
        		String My_Key = marathonDB.getText(DBUtilities.USER_KEY,"NoKey");
        		Log.i(CommonUtilities.LOG_TAG, "登録ログ(ID)："+aray_msg[1]);
        		Log.i(CommonUtilities.LOG_TAG, "登録ログ(名前):"+aray_msg[2]);
        		Log.i(CommonUtilities.LOG_TAG, "登録ログ(受信した認証キー):"+aray_msg[3]);
        		Log.i(CommonUtilities.LOG_TAG, "登録ログ(自身の認証キー):"+My_Key);

    			int RegistID =marathonDB.friendIdSearch(aray_msg[1]);
    			// 既に受信中、もしくは登録済みであれば登録処理を行わない。
    			if(RegistID == -1){
	        		// 認証キーが自身の物と同じか判定し、同じなら登録を行う。違うなら違いますメッセージ送信
	        		if(My_Key.equals(aray_msg[3])){
	        			Log.i(CommonUtilities.LOG_TAG, "YES");

		    			RegNo++;
		    			marathonDB.setInteger(DBUtilities.FRIEND_NUM, RegNo);
		    			marathonDB.setInteger(DBUtilities.FRIEND_STATUS + RegNo,DBUtilities.FRIEND_STATUS_REGIST_WAITTING);
		    			marathonDB.setText(DBUtilities.FRIEND_ID + RegNo, aray_msg[1]);
		    			marathonDB.setText(DBUtilities.FRIEND_NAME + RegNo,aray_msg[2]);
		    			generateNotificationReg(m_Context,aray_msg[1]);
	        		}else{
	        			Log.i(CommonUtilities.LOG_TAG, "NO!");
	        			String IDS[] = {aray_msg[1]};
	        			String My_ID = marathonDB.getText(DBUtilities.USER_ID,"NoKey");
	        			if(My_ID.equals("NoKey")){
	        				// no content
	        			}else{
	        				SendAsyncTask task = new SendAsyncTask(IDS,CommonUtilities.M_TYPE_FAILED_KEY  + ","+ My_ID + "," + aray_msg[3] + ",");
	        				task.execute();
	        			}
	        		}
    			}else{
    				// すでに登録済みであるならば相手に登録許可を送信
    				int Status = marathonDB.getInteger(DBUtilities.FRIEND_STATUS + RegistID, -1);
    				if(Status != -1){
    					if(Status == DBUtilities.FRIEND_STATUS_REGISTERED || Status == DBUtilities.FRIEND_STATUS_RUNNER){
    						// フレンド申請許可を送信
    						String IDS[] = {aray_msg[1]};
    						String My_ID = marathonDB.getText(DBUtilities.USER_ID,"NoKey");
    						String My_Name = marathonDB.getText(DBUtilities.USER_NAME,"NoName");
    	    				SendAsyncTask task = new SendAsyncTask(IDS, CommonUtilities.M_TYPE_FRIEND_APP_OK + ","+ My_ID + "," + My_Name + ",");
    	    				task.execute();
    					}
    				}
    			}
            }

            // 登録完了通知表示処理
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_FRIEND_APP_OK)){
            	// 登録完了したIDを検索
            	int RegNo =marathonDB.friendIdSearch(aray_msg[1]);
            	if(RegNo != -1){
	            	RegNo++;
	            	int f_status = marathonDB.getInteger(DBUtilities.FRIEND_STATUS + RegNo, -1);
	            	if(f_status == DBUtilities.FRIEND_STATUS_REGIST_PENDING){
	            		marathonDB.setText(DBUtilities.FRIEND_ID + RegNo, aray_msg[1]);
	            		marathonDB.setText(DBUtilities.FRIEND_NAME + RegNo,aray_msg[2]);
	            		marathonDB.setInteger(DBUtilities.FRIEND_STATUS + RegNo, DBUtilities.FRIEND_STATUS_REGISTERED);
	            		generateNotificationOK(m_Context, aray_msg[2]);
	            	}
            	}
            }

            // GPS取得要求受信処理
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_GET_GPS)){
            	double latitude = Double.parseDouble(marathonDB.getText(DBUtilities.FRIEND_LATITUDE,"0.0"));
        		double longitude = Double.parseDouble(marathonDB.getText(DBUtilities.FRIEND_LONGITUDE,"0.0"));
        		int section = marathonDB.getInteger(DBUtilities.FRIEND_SECTION, -1);
        		boolean goal_flg = marathonDB.getBoolean(DBUtilities.FRIEND_GOAL, false);
        		boolean mode = marathonDB.getBoolean(DBUtilities.RUNNER_MODE, false);

           		Log.i(CommonUtilities.LOG_TAG,"緯度："+ latitude + " 経度："+longitude + " レーン：" + section + " モード："+ mode);

           		Log.i(CommonUtilities.LOG_TAG, "ゴールしているか(未ゴール.false ゴール済.true):"+ goal_flg);
           		if(goal_flg==false){
           			// ランナーが走行中の為、現在の位置情報を返す。
		       		if(latitude!=0.0 && longitude!=0.0 && section!=-1 && mode == true){
		       			String MyId = marathonDB.getText(DBUtilities.USER_ID,"NoID");
						String[] ids = {aray_msg[1]};
						SendAsyncTask task = new SendAsyncTask(ids,CommonUtilities.M_TYPE_SEND_GPS + ","+ MyId + "," + latitude + "," + longitude + "," + section + ",");
						task.execute();
		       		}
           		}else{
           			// ランナーがゴールしている為、現在ゴールしていることを返す。
           			String MyId = marathonDB.getText(DBUtilities.USER_ID,"NoID");
           			String[] ids = {aray_msg[1]};
           			SendAsyncTask task = new SendAsyncTask(ids,CommonUtilities.M_TYPE_FRIEND_GOAL + ","+ MyId + "," + latitude + "," + longitude + "," + section + ",");
					task.execute();
           		}
            }

            // GPS取得完了処理
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_SEND_GPS)){
            	int RegNo =marathonDB.friendIdSearch(aray_msg[1]);
            	if(RegNo != -1){
	            	RegNo++;
	            	Log.i(CommonUtilities.LOG_TAG,"[" + RegNo + "]緯度：" + aray_msg[2] + " 経度：" + aray_msg[3] + " レーン：" + aray_msg[4]);
	            	marathonDB.setBoolean(DBUtilities.FRIEND_CHAGE_FLG + RegNo,true);
	    	    	marathonDB.setText(DBUtilities.FRIEND_LATITUDE + RegNo, aray_msg[2]);
	    	    	marathonDB.setText(DBUtilities.FRIEND_LONGITUDE + RegNo,aray_msg[3]);
	    	    	marathonDB.setInteger(DBUtilities.FRIEND_SECTION + RegNo, Integer.parseInt(aray_msg[4]));

            	}
            }
            // 相手に削除された時の処理
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_FRIEND_RELEASE)){
            	int RegNo =marathonDB.friendIdSearch(aray_msg[1]);
            	if(RegNo != -1){
            		RegNo++;
            		marathonDB.setBoolean(DBUtilities.FRIEND_CANCEL+RegNo, true);
            		generateNotificationRelease(m_Context,marathonDB.getText(DBUtilities.FRIEND_NAME + RegNo,"NoName") + "さんが登録を解除しました。");
            	}
            }

            // 認証キー不一致処理
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_FAILED_KEY)){
            	int RegNo =marathonDB.friendIdSearch(aray_msg[1]);
            	if(RegNo != -1){
            		RegNo++;
            		marathonDB.setBoolean(DBUtilities.FRIEND_CANCEL+RegNo, true);
            		generateNotificationNG(m_Context,aray_msg[1]);
            	}
            }

            // 認証拒否処理
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_FRIEND_CANCEL)){
            	int RegNo =marathonDB.friendIdSearch(aray_msg[1]);
            	if(RegNo != -1){
            		RegNo++;
            		marathonDB.setBoolean(DBUtilities.FRIEND_CANCEL+RegNo, true);
            		generateNotificationCancel(m_Context,aray_msg[1]);
            	}
            }
            // ゴールした時の処理
            if(aray_msg[0].equals(CommonUtilities.M_TYPE_FRIEND_GOAL)){
            	int RegNo =marathonDB.friendIdSearch(aray_msg[1]);
            	String friend_name="";
            	if(RegNo != -1){
            		RegNo++;
            		friend_name = marathonDB.getText(DBUtilities.FRIEND_NAME + RegNo,"NoName");

            		Log.i(CommonUtilities.LOG_TAG,"ゴールした人の名前:"+friend_name);
            		Log.i(CommonUtilities.LOG_TAG,"ゴールした人の緯度:"+ aray_msg[2]);
            		Log.i(CommonUtilities.LOG_TAG,"ゴールした人の経度:"+ aray_msg[3]);
            		Log.i(CommonUtilities.LOG_TAG,"ゴールした人のレーン番号："+ aray_msg[4]);

            		marathonDB.setBoolean(DBUtilities.FRIEND_CHAGE_FLG + RegNo,true);
	    	    	marathonDB.setText(DBUtilities.FRIEND_LATITUDE + RegNo, aray_msg[2]);
	    	    	marathonDB.setText(DBUtilities.FRIEND_LONGITUDE + RegNo,aray_msg[3]);
	    	    	marathonDB.setInteger(DBUtilities.FRIEND_SECTION + RegNo, Integer.parseInt(aray_msg[4]));


            	}
            	generateNotificationGoal(m_Context,friend_name+"さんがゴールしました！");
            }
    	}
    }


	@Override
	protected void onError(Context arg0, String arg1) {
		// TODO 自動生成されたメソッド・スタブ

	}

}
